#pragma once

#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

using namespace std;

const string gpipeFile = "./fifo";
// 默认权限 普通文件默认其实权限777
// 这里相当于拥有者有读写权限 mode_t就是unsigned int
const mode_t gFifomode = 0600;
// 定义全局缺省fd
const int gdefaultFd = -1;
// 定义缓冲区大小 一次性读多少字节
const int gsize = 1024;
// 定义读写模式
const int gForRead = O_RDONLY;
const int gForWrite = O_WRONLY;

class Fifo
{
private:
    void OpenFifo(int flag)
    {
        _fd = ::open(gpipeFile.c_str(), flag);
        if (_fd < 0)
        {
            cerr << "open error" << endl;
        }
    }

public:
    Fifo()
        : _fd(-1)
    {
        // 指定权限掩码
        umask(0);
        // 创建命名管道
        int n = mkfifo(gpipeFile.c_str(), gFifomode);
        if (n < 0)
        {
            //cerr << "mkfifo error" << endl;
            return;
        }
        cout << "mkfifo success" << endl;
    }

    // 打开管道
    bool OpenPipeForWrite()
    {
        // 指定客户端读取文件 打开文件以只写方式
        OpenFifo(gForWrite);
        if (_fd < 0)
        {
            cerr << "open error" << endl;
            return false;
        }
        return true;
    }

    // 打开管道
    bool OpenPipeForRead()
    {
        // 指定服务端读取文件 打开文件以只读方式
        OpenFifo(gForRead);
        if (_fd < 0)
        {
            return false;
        }
        return true;
    }
    
    // 相当于读
    int Wait()
    {
        int code = 0;
        ssize_t n = ::read(_fd, &code, sizeof(code));
        if (n == sizeof(code))
        {
            return 1;
        }
        else if (n == 0)
        {
            return 0;
        }
        return 2;
    }

    // 相当于写
    void Signal()
    {
        int code = 1;
        ::write(_fd, &code, sizeof(code));
    }

    ~Fifo()
    {
        if (_fd >= 0)
            ::close(_fd);
        int n = ::unlink(gpipeFile.c_str());
        if (n < 0)
        {
            cerr << "unlink error" << endl;
            return;
        }
        cout << "unlink success" << endl;
    }

private:
    int _fd;
};

// 定义一个Fifo
Fifo gPipe;